package com.atguigu.ad.hive.udf;

import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;

import java.util.ArrayList;

/**
 * @author yhm
 * @create 2023-02-14 14:04
 */
public class ParseUA extends GenericUDF {
    @Override
    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
        // 判断参数的个数是否为1个
        if (arguments.length != 1){
            throw new UDFArgumentException("parse_ua的参数必须是1个");
        }

        // 判断参数的类型
        ObjectInspector uaOI = arguments[0];
        if (!ObjectInspector.Category.PRIMITIVE.equals(uaOI.getCategory())) {
            throw new UDFArgumentException("parse_ua的参数必须是基本数据类型");
        }
        PrimitiveObjectInspector uaOI1 = (PrimitiveObjectInspector) uaOI;
        if (!PrimitiveObjectInspector.PrimitiveCategory.STRING.equals(uaOI1.getPrimitiveCategory())) {
            throw new UDFArgumentException("parse_ua的参数必须是string类型");
        }
        // 限定传出参数的类型
        ArrayList<String> structFieldNames = new ArrayList<>();
        ArrayList<ObjectInspector> structFieldOIs = new ArrayList<>();

        structFieldNames.add("browser");
        structFieldNames.add("browserVersion");
        structFieldNames.add("engine");
        structFieldNames.add("engineVersion");
        structFieldNames.add("os");
        structFieldNames.add("osVersion");
        structFieldNames.add("platform");
        structFieldNames.add("isMobile");

        structFieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
        structFieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
        structFieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
        structFieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
        structFieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
        structFieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
        structFieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
        structFieldOIs.add(PrimitiveObjectInspectorFactory.javaBooleanObjectInspector);

        return ObjectInspectorFactory.getStandardStructObjectInspector(structFieldNames,structFieldOIs);
    }

    @Override
    public Object evaluate(DeferredObject[] arguments) throws HiveException {
        String ua = arguments[0].get().toString();
        UserAgent userAgent = UserAgentUtil.parse(ua);
        ArrayList<Object> result = new ArrayList<>();
        result.add(userAgent.getBrowser().getName());
        result.add(userAgent.getVersion());
        result.add(userAgent.getEngine().getName());
        result.add(userAgent.getEngineVersion());
        result.add(userAgent.getOs().getName());
        result.add(userAgent.getOsVersion());
        result.add(userAgent.getPlatform());
        result.add(userAgent.isMobile());

        return result;
    }

    @Override
    public String getDisplayString(String[] children) {
        return getStandardDisplayString("parse_ua", children);
    }
}
